package com.srwl.mytx.activity;

import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.media.projection.MediaProjectionManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import com.alibaba.fastjson.JSONObject;
import com.srwl.mytx.Constant;
import com.srwl.mytx.Helper;
import com.srwl.mytx.R;
import com.srwl.mytx.RetrofitManager;
import com.srwl.mytx.dao.DBManager;
import com.srwl.mytx.domain.CommonResult;
import com.srwl.mytx.domain.User;
import com.srwl.mytx.service.UserService;
import com.srwl.mytx.utils.ClickUtil;
import com.srwl.mytx.utils.GlideLoadUtils;
import com.srwl.mytx.utils.PermissionsUtils;
import com.srwl.mytx.widget.ConfirmDialog;
import com.starrtc.starrtcsdk.api.XHClient;
import com.starrtc.starrtcsdk.api.XHConstants;
import com.starrtc.starrtcsdk.api.XHCustomConfig;
import com.starrtc.starrtcsdk.api.XHSDKHelper;
import com.starrtc.starrtcsdk.api.XHVoipManager;
import com.starrtc.starrtcsdk.apiInterface.IXHResultCallback;
import com.starrtc.starrtcsdk.core.audio.StarRTCAudioManager;
import com.starrtc.starrtcsdk.core.player.StarPlayer;
import com.starrtc.starrtcsdk.core.pusher.XHCameraRecorder;
import com.starrtc.starrtcsdk.core.pusher.XHScreenRecorder;

import java.util.List;
import java.util.Set;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;


public class VideoChatActivity extends BaseActivity implements View.OnClickListener {
    private static final String TAG = "VideoChatActivity";
    private XHVoipManager voipManager;

    // private Chronometer timer;

    public static String ACTION = "ACTION";
    public static String RING = "RING";
    public static String CALLING = "CALLING";
    private String action;
    private User targetUser;
    private String targetUserId;
    private Boolean isTalking = false;

    private StarRTCAudioManager starRTCAudioManager;
    private XHSDKHelper xhsdkHelper;
    @BindView(R.id.voip_surface_target)
    StarPlayer targetPlayer;
    @BindView(R.id.voip_surface_self)
    StarPlayer selfPlayer;
    //    @BindView(R.id.voip_preview)
    //  StarPlayer previewPlayer;
    @BindView(R.id.tv_nick)
    TextView tv_nick;
    @BindView(R.id.iv_avatar)
    ImageView iv_avatar;
    @BindView(R.id.tv_status)
    TextView tv_status;
    @BindView(R.id.ll_ready)
    View ll_ready;
    @BindView(R.id.iv_receive)
    ImageView iv_receive;
    @BindView(R.id.ll_start_call)
    View ll_startCall;
    @BindView(R.id.rl_control_local_video)
    RelativeLayout rl_controlLocalVideo;
    @BindView(R.id.rl_switch_camera)
    RelativeLayout rl_switchCamera;
    @BindView(R.id.rl_user_info)
    RelativeLayout rl_userInfo;

    private BroadcastReceiver receiver;
    private LocalBroadcastManager broadcastManager;
    private Ringtone ringtone;
    private boolean selfSmallSize = true;
    private static final int REQUEST_CODE = 1;
    private MediaProjectionManager mMediaProjectionManager;
    private XHScreenRecorder mRecorder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //设置不黑屏等
        getWindow().addFlags(
                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                        | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                        | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
        starRTCAudioManager = StarRTCAudioManager.create(this.getApplicationContext());
        starRTCAudioManager.start(new StarRTCAudioManager.AudioManagerEvents() {
            @Override
            public void onAudioDeviceChanged(StarRTCAudioManager.AudioDevice selectedAudioDevice, Set availableAudioDevices) {
                Log.d("onAudioDeviceChanged ", selectedAudioDevice.name());
            }
        });
        //  XHCustomConfig.getInstance(this).setDefConfigAudioSource(XHConstants.XHAudioSourceEnum.MIC);
        // XHCustomConfig.getInstance(this).setDefConfigAudioStreamType(XHConstants.XHAudioStreamTypeEnum.STREAM_MUSIC);
//        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_video_chat_1);
        ButterKnife.bind(this);
        registerBroadcastReceiver();
        XHCustomConfig customConfig = XHCustomConfig.getInstance(this);
        customConfig.setDefConfigAudioSource(XHConstants.XHAudioSourceEnum.VOICE_COMMUNICATION);
        customConfig.setDefConfigAudioStreamType(XHConstants.XHAudioStreamTypeEnum.STREAM_VOICE_CALL);
        voipManager = XHClient.getInstance().getVoipManager();
        voipManager.setRtcMediaType(XHConstants.XHRtcMediaTypeEnum.STAR_RTC_MEDIA_TYPE_VIDEO_AND_AUDIO);
        voipManager.setRecorder(new XHCameraRecorder());
        targetUser = getIntent().getParcelableExtra("targetUserInfo");
        if (targetUser == null) {
            targetUserId = getIntent().getStringExtra("userId");
            targetUser = Helper.getInstance().getContactUserInfo(targetUserId);
            if (targetUser == null) {
                getUserInfo(targetUserId);
            }
        } else {
            targetUserId = targetUser.getuId();
        }
        action = getIntent().getStringExtra(ACTION);
        showTargetUserInfo();
        findViewById(R.id.rl_voice_controller).setOnClickListener(this);
        //selfPlayer.setZOrderMediaOverlay(true);
        // timer = findViewById(R.id.timer);
        selfPlayer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if (selfSmallSize) {
                    selfSmallSize = false;
                    voipManager.setupView(targetPlayer, selfPlayer, new IXHResultCallback() {
                        @Override
                        public void success(Object data) {
                            Log.d(TAG, "切换视频成功，把自己的视频切换为大屏 success");
                        }

                        @Override
                        public void failed(String errMsg) {
                            Log.e(TAG, "setupView failed");
                            //  stopAndFinish();
                        }
                    });
                } else {
                    selfSmallSize = true;
                    voipManager.setupView(selfPlayer, targetPlayer, new IXHResultCallback() {
                        @Override
                        public void success(Object data) {
                            Log.d(TAG, "切换视频成功，把自己的视频切换为大屏 success");
                        }

                        @Override
                        public void failed(String errMsg) {
                            Log.e(TAG, "setupView failed");
                            //  stopAndFinish();
                        }
                    });
                }

            }
        });


        rl_switchCamera.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                voipManager.switchCamera();
            }
        });

        if (action.equals(CALLING)) {
//            Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
//            ringtone = RingtoneManager.getRingtone(this, notification);
//            ringtone.play();

        } else {
            Log.d("newVoip", "onPickup");
            tv_status.setText("视频通话等待接听");
            // onPickup();
            Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
            ringtone = RingtoneManager.getRingtone(this, notification);
            ringtone.play();
        }
    }


    @Override
    protected void onStart() {
        super.onStart();
        String[] permissions;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            permissions = new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA};
        } else {
            permissions = new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CAMERA};
        }
        PermissionsUtils.getInstance().checkPermissions(this, permissions, new PermissionsUtils.IPermissionsResult() {
            @Override
            public void onGranted() {
                previewAndCallOrReceive();
            }


            @Override
            public void onDenied(List<String> deniedPermissionList) {
                StringBuilder tips = new StringBuilder();
                for (String permission : deniedPermissionList) {
                    if (Manifest.permission.RECORD_AUDIO.equals(permission)) {
                        tips.append("[麦克风] ");
                    } else if (Manifest.permission.READ_EXTERNAL_STORAGE.equals(permission)) {
                        tips.append("[储存空间] ");
                    } else if (Manifest.permission.CAMERA.equals(permission)) {
                        tips.append("[相机] ");
                    }
                }
                ConfirmDialog dialog = new ConfirmDialog(VideoChatActivity.this, "提醒", "使用 " + tips + "的权限被禁止，去设置？", "去设置", "取消", true);
                dialog.setConfirmListener(new ConfirmDialog.ConfirmListener() {
                    @Override
                    public void confirm() {
                        Uri packageURI = Uri.parse("package:" + getPackageName());
                        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI);
                        startActivity(intent);
                    }
                });
                dialog.setCancelListener(new ConfirmDialog.CancelListener() {
                    @Override
                    public void cancel() {
                        finish();
                    }
                });
                dialog.setCanceledOnTouchOutside(false);
                dialog.show();
            }
        });
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        PermissionsUtils.getInstance().onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    /**
     * 在权限校验之后，开启预览
     * 并接听或者呼叫
     */
    private void previewAndCallOrReceive() {
        //显示预览
        xhsdkHelper = new XHSDKHelper();
        xhsdkHelper.setDefaultCameraId(1);
        xhsdkHelper.startPerview(this, targetPlayer);
        if (action.equals(CALLING)) {
            showCallingView();
            Log.d("newVoip", "call");
            voipManager.call(this, targetUserId, new IXHResultCallback() {
                @Override
                public void success(Object data) {
                    Log.d("newVoip", "call success");
                    xhsdkHelper.stopPerview();
                    xhsdkHelper = null;
                }

                @Override
                public void failed(String errMsg) {
                    Log.d("newVoip", "call failed");
                    stopAndFinish();
                }
            });
        } else {

        }
    }

    private void showTargetUserInfo() {
        if (targetUser != null) {
            //Glide.with(this).load(targetUser.getAvatar()).error(R.drawable.tx_default_avatar_1).into(iv_avatar);
            GlideLoadUtils.glideLoad(this, targetUser.getAvatar(), iv_avatar, R.drawable.tx_default_avatar_1);
            String username = targetUser.getUsername();
            if (username == null) {
                username = targetUser.getNick();
            }
            tv_nick.setText(username);
        }
    }

    private void setupViews() {
        isTalking = true;
        voipManager.setupView(selfPlayer, targetPlayer, new IXHResultCallback() {
            @Override
            public void success(Object data) {
                Log.d(TAG, "setupView success");
            }

            @Override
            public void failed(String errMsg) {
                Log.e(TAG, "setupView failed");
                stopAndFinish();
            }
        });
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
//        if (starRTCAudioManager != null) {
//            starRTCAudioManager.stop();
//        }
//        if (xhsdkHelper != null) {
//            xhsdkHelper.stopPerview();
//        }

        if (ringtone != null) {
            ringtone.stop();
        }
        broadcastManager.unregisterReceiver(receiver);
        PermissionsUtils.getInstance().clear();
    }


    public void onBackPressed() {
        new AlertDialog.Builder(VideoChatActivity.this).setCancelable(true)
                .setTitle("是否挂断?")
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface arg0, int arg1) {

                    }
                }).setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface arg0, int arg1) {
                        //timer.stop();
                        voipManager.hangup(new IXHResultCallback() {
                            @Override
                            public void success(Object data) {

                                stopAndFinish();
                            }

                            @Override
                            public void failed(final String errMsg) {
                                Log.d("", "AEVENT_VOIP_ON_STOP errMsg:" + errMsg);

                            }
                        });
                    }
                }
        ).show();
    }

//    @Override
//    public void dispatchEvent(String aEventID, boolean success, final Object eventObj) {
//        super.dispatchEvent(aEventID,success,eventObj);
//        switch (aEventID){
//            case AEvent.AEVENT_VOIP_REV_BUSY:
//                Log.d("","对方线路忙");
//                Log.showMsg(VideoChatActivity.this,"对方线路忙");
//                stopAndFinish();
//                break;
//            case AEvent.AEVENT_VOIP_REV_REFUSED:
//                Log.d("","对方拒绝通话");
//                Log.showMsg(VideoChatActivity.this,"对方拒绝通话");
//                stopAndFinish();
//                break;
//            case AEvent.AEVENT_VOIP_REV_HANGUP:
//                Log.d("","对方已挂断");
//                Log.showMsg(VideoChatActivity.this,"对方已挂断");
//                timer.stop();
//                stopAndFinish();
//                break;
//            case AEvent.AEVENT_VOIP_REV_CONNECT:
//                Log.d("","对方允许通话");
//                showTalkingView();
//                break;
//            case AEvent.AEVENT_VOIP_REV_ERROR:
//                Log.d("",(String) eventObj);
//                stopAndFinish();
//                break;
//            case AEvent.AEVENT_VOIP_TRANS_STATE_CHANGED:
//                findViewById(R.id.state).setBackgroundColor(((int)eventObj==0)?0xFFFFFF00:0xFF299401);
//                break;
//        }
//    }


    /**
     * 视频对话呼叫方在对方没有接通之前，显示一个挂断按键
     */
    private void showCallingView() {

        ll_ready.setVisibility(View.VISIBLE);
        iv_receive.setVisibility(View.GONE);
        ll_startCall.setVisibility(View.GONE);
    }

    private void showTalkingView() {

        //timer.setBase(SystemClock.elapsedRealtime());
        //timer.start();
        setupViews();
    }

    //接听 视频通话
    private void onPickup() {
        ringtone.stop();
        xhsdkHelper.stopPerview();
        voipManager.accept(this, targetUser.getuId(), new IXHResultCallback() {
            @Override
            public void success(Object data) {
                Log.d("newVoip", "onPickup OK ");
            }

            @Override
            public void failed(String errMsg) {
                Log.d("newVoip", "onPickup failed ");
                stopAndFinish();
            }
        });
        rl_userInfo.setVisibility(View.GONE);
        ll_ready.setVisibility(View.GONE);
        ll_startCall.setVisibility(View.VISIBLE);

        showTalkingView();
    }

    //拒绝视频通话
    private void refuse() {
        voipManager.refuse(new IXHResultCallback() {
            @Override
            public void success(Object data) {
                Log.i(TAG, "success: 拒绝接听成功");
            }

            @Override
            public void failed(String errMsg) {
                Log.e(TAG, "failed: 拒绝接听失败");
            }
        });

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.calling_hangup:
                cancelCall();
                break;
            case R.id.talking_hangup:
                hangUp();
                break;
            case R.id.screen_btn:
                if (!XHCustomConfig.getInstance(VideoChatActivity.this).getHardwareEnable()) {

                    Log.i(TAG, "onClick: 需要打开硬编模式");
                    return;
                }
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    if (mRecorder != null) {
                        findViewById(R.id.screen_btn).setSelected(false);
                        voipManager.resetRecorder(new XHCameraRecorder());
                        mRecorder = null;
                    } else {
                        if (mMediaProjectionManager == null) {
                            mMediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
                        }
                        Intent captureIntent = mMediaProjectionManager.createScreenCaptureIntent();
                        startActivityForResult(captureIntent, REQUEST_CODE);
                    }
                } else {
                    Log.e(TAG, "系统版本过低，无法使用录屏功能");
                }
                break;
            case R.id.camera_btn:
                if (findViewById(R.id.camera_btn).isSelected()) {
                    findViewById(R.id.camera_btn).setSelected(false);
                    voipManager.setVideoEnable(false);
                } else {
                    findViewById(R.id.camera_btn).setSelected(true);
                    voipManager.setVideoEnable(true);
                }
                break;
            case R.id.rl_voice_controller:
                if (findViewById(R.id.mic_btn).isSelected()) {
                    findViewById(R.id.mic_btn).setSelected(false);
                    voipManager.setAudioEnable(true);
                } else {
                    findViewById(R.id.mic_btn).setSelected(true);
                    voipManager.setAudioEnable(false);
                }
                break;
        }
    }

    /**
     * 取消呼叫
     */
    private void cancelCall() {
        voipManager.cancel(new IXHResultCallback() {
            @Override
            public void success(Object data) {
                stopAndFinish();
            }

            @Override
            public void failed(String errMsg) {
                stopAndFinish();
            }
        });
    }

    //挂断
    private void hangUp() {
        voipManager.hangup(new IXHResultCallback() {
            @Override
            public void success(Object data) {

                Log.i(TAG, "success: 挂断成功");

            }

            @Override
            public void failed(String errMsg) {
                Log.e(TAG, "failed: 挂断失败" + errMsg);
            }
        });
    }


    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        mRecorder = new XHScreenRecorder(this, resultCode, data);
        voipManager.resetRecorder(mRecorder);
        findViewById(R.id.screen_btn).setSelected(true);
    }

    private void stopAndFinish() {
        if (starRTCAudioManager != null) {
            starRTCAudioManager.stop();
        }
        postDelayedFinish(1500);
    }

    @OnClick(R.id.iv_receive)
    public void onReceiveCall() {
        if (ClickUtil.isFastClick()) {
            return;
        }
        tv_status.setText("连接中...");
        onPickup();
    }

    @OnClick(R.id.iv_refuse_call)
    public void onRefuseCall() {
        if (ClickUtil.isFastClick()) {
            return;
        }
        //如果是被呼叫方，那么这个按键就是拒绝接听，如果是呼叫方，那就是主动取消呼叫
        if (action.equals(CALLING)) {

            tv_status.setText("取消呼叫");
            cancelCall();
            xhsdkHelper.stopPerview();
            //stopAndFinish();
        } else {
            //如果是呼叫失败，直接延迟1s后退出
            tv_status.setText("拒绝接听");
            refuse();
            ringtone.stop();
            xhsdkHelper.stopPerview();
            stopAndFinish();
        }
    }

    @OnClick(R.id.iv_end_call)
    public void endCall() {
        if (ClickUtil.isFastClick()) {
            return;
        }
        hangUp();
        stopAndFinish();
    }

    private void postDelayedFinish(int delayMillis) {
        Helper.getInstance().setStartingCall(false);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                finish();
            }
        }, delayMillis);
    }


    private void registerBroadcastReceiver() {

        broadcastManager = LocalBroadcastManager.getInstance(this);
        IntentFilter filter = new IntentFilter();

        filter.addAction(Constant.ACTION_ON_HANG_UP);
        filter.addAction(Constant.ACTION_ON_CALL_ERROR);
        filter.addAction(Constant.ACTION_ON_AUDIO_CONNECT);
        filter.addAction(Constant.ACTION_ON_CALL_BE_REFUSE);
        filter.addAction(Constant.ACTION_ON_CALL_BUSY);

        receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {

                switch (intent.getAction()) {

                    case Constant.ACTION_ON_AUDIO_CONNECT:
                        rl_userInfo.setVisibility(View.GONE);
                        ll_ready.setVisibility(View.GONE);
                        ll_startCall.setVisibility(View.VISIBLE);
                        setupViews();
                        break;

                    case Constant.ACTION_ON_HANG_UP:

                        if (isTalking) {
                            tv_status.setText("对方已经挂断");
                            rl_userInfo.setVisibility(View.VISIBLE);
                        } else {
                            ringtone.stop();
                            tv_status.setText("对方已经取消呼叫");
                            if (xhsdkHelper != null) {
                                xhsdkHelper.stopPerview();
                            }
                        }
                        stopAndFinish();
                        break;
                    case Constant.ACTION_ON_CALL_ERROR:

                        tv_status.setText("发起视频通话出错");
                        if (xhsdkHelper != null) {
                            xhsdkHelper.stopPerview();
                        }
                        stopAndFinish();
                        break;
                    case Constant.ACTION_ON_CALL_BE_REFUSE:
                        tv_status.setText("对方拒绝接听");
                        if (xhsdkHelper != null) {
                            xhsdkHelper.stopPerview();
                        }
                        stopAndFinish();
                        break;

                    case Constant.ACTION_ON_CALL_BUSY:
                        tv_status.setText("对方正在通话中");
                        if (xhsdkHelper != null) {
                            xhsdkHelper.stopPerview();
                        }
                        stopAndFinish();
                        break;


                }
            }
        };
        broadcastManager.registerReceiver(receiver, filter);

    }

    /**
     * 远程查询用户信息
     *
     * @param userId
     */
    private void getUserInfo(String userId) {
        RetrofitManager.getInstance().createRequest(UserService.class)
                .getUserInfo(userId)
                .enqueue(new Callback<CommonResult>() {
                    @Override
                    public void onResponse(Call<CommonResult> call, Response<CommonResult> response) {
                        CommonResult result = response.body();
                        if (!response.isSuccessful() || result == null) {
                            Log.e(TAG, "onResponse:从服务端获取联系人信息出错 " + response.message());
                            return;
                        }

                        if (result.isError()) {
                            Log.e(TAG, "onResponse:从服务端获取联系人信息出错 " + result.getMsg());
                            return;
                        }

                        JSONObject object = (JSONObject) result.getData();

                        User user = object.toJavaObject(User.class);
                        user.setUId(userId);
                        user.setType(Constant.USER_TYPE_TEMP);
                        DBManager.getInstance().getDaoSession().getUserDao().insertOrReplace(user);//作为临时联系人，保存在用户表中
                        targetUser = user;
                        showTargetUserInfo();
                    }

                    @Override
                    public void onFailure(Call<CommonResult> call, Throwable t) {

                        Log.e(TAG, "onFailure: " + t.getMessage());
                    }
                });
    }

}
